/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sun.scheduler.gui;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import sun.scheduler.core.resource.*;
import javax.swing.JComponent;
import javax.swing.ToolTipManager;
import sun.scheduler.core.*;

/**
 *
 * @author taiGa
 */
public class LevelingPanel extends javax.swing.JPanel implements MouseMotionListener, MouseListener {

    private ArrayList<Box> aB = null;
    private ArrayList<Point> curve = null;
    private float maxX = 0, maxY = 0, minX = Float.MAX_VALUE, minY = Float.MAX_VALUE;
    private double scaleX, scaleY;
    private int offsetX = 20;
    private int offsetY = 20;
    private String summary;
    private ResourceProfile resourceProfile;

    public ResourceProfile getResourceProfiles() {
        return resourceProfile;
    }

    public void setResourceProfiles(ResourceProfile resourceProfiles) {
        if(resourceProfiles != null) {
        this.resourceProfile = resourceProfiles;
        calculateScale();
        calculateBoxes();
        }
        
    }

    public float getMaxX() {
        return maxX;
    }

    public void setMaxX(float maxX) {
        this.maxX = maxX;
        calculateScale();
    }

    public float getMaxY() {
        return maxY;
    }

    public void setMaxY(float maxY) {
        this.maxY = maxY;
        
    }

    public float getMinX() {
        return minX;
    }

    public void setMinX(float minX) {
        this.minX = minX;
    }

    public float getMinY() {
        return minY;
    }

    public void setMinY(float minY) {
        this.minY = minY;
    }

    public int getOffsetX() {
        return offsetX;
    }

    public void setOffsetX(int offsetX) {
        this.offsetX = offsetX;
    }

    public int getOffsetY() {
        return offsetY;
    }

    public void setOffsetY(int offsetY) {
        this.offsetY = offsetY;
    }

    public double getScaleX() {
        return scaleX;
    }

    public void setScaleX(double scaleX) {
        this.scaleX = scaleX;
    }

    public double getScaleY() {
        return scaleY;
    }

    public void setScaleY(double scaleY) {
        this.scaleY = scaleY;
    }

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public void calculateBoxes() {
        if (resourceProfile != null) {
            aB = new ArrayList<Box>();

            long start = 0, end;
            while ((end = resourceProfile.next(start)) != start) {
                addaB((long) start, (long) resourceProfile.cost(start), (long) resourceProfile.cost(start), (long) end - 1, resourceProfile.getResource().info.name, Color.BLACK);
                start = end;
            }
            //System.out.println("aB :" + aB.toString());

        }


    }

    /**
     * Creates new form LevelingPanel
     */
    public LevelingPanel() {
        super();
        this.setSize(457, 713);
        this.addMouseMotionListener(this);
        this.addMouseListener(this);
        if (aB == null) {
            aB = new ArrayList<Box>();
        }
        initComponents();
    }

    public void calculateScale() {
        maxY = 0;
        minY = Float.MAX_VALUE;
        for (Box b : aB) {
            // maxima
            if (b.getY() > maxY) {
                maxY = (float) b.getY();
            }

            // minima
            if (b.getY() - b.getBoxHeight() < minY) {
                minY = (float) b.getY() - b.getBoxHeight();

            }
        }
        float diffX = (maxX - minX), diffY = (maxY - minY), diff = diffX;
        if (diffX > diffY) {
            diff = diffY;
        }

        scaleX = (double) (getWidth() - offsetX) / diffX;
        scaleY = (double) (getHeight() - offsetY) / diffY;
    }

    @Override
    public void paintComponent(Graphics g) {
        calculateScale();
        calculateBoxes();
        
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, getWidth(), getHeight());
        super.paintComponent(g2d);
        if (aB.size() < 1) {
            Font font = new Font("Arial", Font.BOLD, 24);
            g2d.setFont(font);
            g2d.setColor(Color.DARK_GRAY);
            g2d.drawString("Click on a resource to get a solution shown here!", getWidth() / 2 - 250, getHeight() / 2);
        }
        for (Box b : aB) {
            g2d.setColor(Color.BLACK);
            Rectangle2D rec = new Rectangle2D.Double(b.posX * scaleX + offsetX, getHeight() - b.posY * scaleY + offsetY, b.getBoxLength()*scaleX, b.boxHeight*scaleY);
            g2d.draw(rec);
            g2d.fill(rec);
        }
    }

    public ArrayList<Box> getaB() {
        return aB;
    }

    public void addaB(float x, float y, float boxlenght, float boxwidth, String resName) {
        if (aB == null) {
            aB = new ArrayList<Box>();
        }
        aB.add(new Box(x, y, boxlenght, boxwidth, resName, Color.BLACK));
    }

    public void addaB(float x, float y, float boxlenght, float boxwidth, String resName, Color c) {
        if (aB == null) {
            aB = new ArrayList<Box>();
        }
        aB.add(new Box(x, y, boxlenght, boxwidth, resName, c));
    }

    public void resetaB() {
        aB = new ArrayList<Box>();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables

    @Override
    public void mouseDragged(MouseEvent e) {
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        boolean is = false;
        Point p = new Point();
        JComponent component = (JComponent) e.getSource();

        for (Box b : aB) {
            p.setLocation(e.getX(), e.getY());
            Rectangle2D rec = new Rectangle2D.Double(b.posX * scaleX + offsetX, getHeight() - b.posY * scaleY + offsetY, b.getBoxLength() * scaleX, b.boxHeight * scaleY);
            if (rec.contains(p)) {
                ToolTipManager.sharedInstance().setInitialDelay(0);
                component.setToolTipText("Resource: " + b.getResName() + " | Time: " + b.getX() + " | Cost: " + b.getY());
                is = true;


            }
        }
        if (!is) {
            ToolTipManager.sharedInstance().setInitialDelay(500);
            component.setToolTipText(null);
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
//        curve = new ArrayList<Point>();
//        Point p = new Point();
//        for (Box b : aB) {
//            p.setLocation(e.getX(), e.getY());
//            Rectangle2D rec = new Rectangle2D.Double(b.posX * scaleX + offsetX, getHeight() - b.posY * scaleY + offsetY, b.getBoxLength() * scaleX, b.boxHeight * scaleY);
//            if (rec.contains(p)) {
//                int j = 0;
//                if (b.getResProfile() != null) {
//                    do {
//                        Point point = new Point();
//                        point.setLocation(j, b.getResProfile().next(j));
//                        curve.add(point);
//                    } while (b.getResProfile().next(j) != b.getResProfile().next(j + 1));
//                }
//                this.repaint();
//            }
//        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    public class Box {

        private float boxHeight, boxLength, posX, posY;
        private Color c;
        private String resName;

        public Box(float posX, float posY, float boxHeight, float boxLength, String resName, Color c) {
            this.boxHeight = boxHeight;
            this.boxLength = boxLength;
            this.posX = posX;
            this.posY = posY;
            this.c = c;
            this.resName = resName;
        }

        public Color getC() {
            return c;
        }

        public void setC(Color c) {
            this.c = c;
        }

        public String getResName() {
            return resName;
        }

        public void setResName(String resName) {
            this.resName = resName;
        }

        public float getBoxHeight() {
            return boxHeight;
        }

        public void setBoxHeight(float boxHeight) {
            this.boxHeight = boxHeight;
        }

        public float getBoxLength() {
            return boxLength;
        }

        public void setBoxLength(float boxLength) {
            this.boxLength = boxLength;
        }

        @Override
        public String toString() {
            return "Box{" + "boxHeight=" + boxHeight + ", boxLength=" + boxLength + ", posX=" + posX + ", posY=" + posY + ", c=" + c + '}';
        }

        public float getX() {
            return posX;
        }

        public void setX(float posX) {
            this.posX = posX;
        }

        public float getY() {
            return posY;
        }

        public void setY(float posY) {
            this.posY = posY;
        }

        public void paintBox(Graphics2D g2d) {
            g2d.draw(new Rectangle2D.Double(posX, posY, boxLength, boxHeight));
        }
    }
}
